function greeter(person: string) {
  return "Hello, " + person
}

let user = "Jane User"

type C = { a: string; b?: string }

const c: C = { a: "1" }

interface LabelledValue {
  label: string
}

function printLabel(labelledObj: LabelledValue): LabelledValue {
  console.log(labelledObj.label)
  return labelledObj
}

let myObj = { size: 10, label: "Size 10 Object" }
printLabel(myObj)

// 可选属性
interface SquareConfig {
  color?: string
  width?: number
  // [propName: string]: any // 额外参数处理1
}

function createSquare(config: SquareConfig): { color: string; area: number } {
  let newSquare = { color: "white", area: 100 }
  if (config.color) {
    // Error: Property 'clor' does not exist on type 'SquareConfig'
    // newSquare.color = config.clor
  }
  if (config.width) {
    newSquare.area = config.width * config.width
  }
  return newSquare
}

// createSquare({ colosr: "white", width: 111 } as SquareConfig) // 额外参数处理2， 或者用外部对象来当参数也可以处理额外参数
createSquare({ colosr: "white", width: 111 })

// 直接用对象值来做参数会提示报错，但使用变量来做参数时不会，但是我们可以预先对变量类型规定
const cwValue: SquareConfig = { colosr: "white", width: 111 }

createSquare(cwValue)

// 只读属性
interface Point {
  readonly x: number
  readonly y: number
}

let p1: Point = { x: 1, y: 2 }

// p1.x = 22 // 只读属性不可编辑

// 只读数组
let arr1: Array<number> = [1, 2, 3, 4]

const roArr: ReadonlyArray<number> = arr1

// roArr[0] = 12 // error!
// roArr.push(5) // error!
// roArr.length = 100 // error!
// arr1 = roArr   // error!

arr1 = roArr as number[] // error!

// arr1 === roArr; // true

document.body.innerHTML = greeter(user)
